package com.study.demo.mybatisplus.CustomSqlInjector;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.injector.AbstractLogicMethod;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 根据 ID 更新有值字段
 * @author: elvin
 * @time: 2019-02-22 15:09
 * @desc:
 **/
public class LogicUpdateAllColumnById extends AbstractLogicMethod {

    private static Logger log = LoggerFactory.getLogger(LogicUpdateAllColumnById.class);

    @Override
    public MappedStatement injectMappedStatement(final Class<?> mapperClass, final Class<?> modelClass, final TableInfo tableInfo) {
        final String sql;
        final boolean logicDelete = tableInfo.isLogicDelete();
        final SqlMethod sqlMethod = SqlMethod.LOGIC_UPDATE_ALL_COLUMN_BY_ID;
        final StringBuilder append = new StringBuilder("<if test=\"et instanceof java.util.Map\">")
                .append("<if test=\"et.").append(OptimisticLockerInterceptor.MP_OPTLOCK_VERSION_ORIGINAL).append("!=null\">")
                .append(" AND ${et.").append(OptimisticLockerInterceptor.MP_OPTLOCK_VERSION_COLUMN)
                .append("}=#{et.").append(OptimisticLockerInterceptor.MP_OPTLOCK_VERSION_ORIGINAL).append(StringPool.RIGHT_BRACE)
                .append("</if></if>");
        if (logicDelete) {
            append.append(tableInfo.getLogicDeleteSql(true, false));
        }

        // 反射修改fieldFill值为update
        final List<TableFieldInfo> fieldList = tableInfo.getFieldList();
        for (final TableFieldInfo tableFieldInfo : fieldList) {
            final Class<? extends TableFieldInfo> aClass = tableFieldInfo.getClass();
            try {
                final Field fieldFill = aClass.getDeclaredField("fieldFill");
                fieldFill.setAccessible(true);
                fieldFill.set(tableFieldInfo, FieldFill.UPDATE);
            } catch (final NoSuchFieldException e) {
                log.error("获取fieldFill失败", e);
            } catch (final IllegalAccessException e) {
                log.error("设置fieldFill失败", e);
            }

        }
        sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(),
                this.sqlSet(logicDelete, false, tableInfo, Constants.ENTITY_SPOT),
                tableInfo.getKeyColumn(), Constants.ENTITY_SPOT + tableInfo.getKeyProperty(),
                append);
        final SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
        return this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
    }
}
